算法--快速排序(Java)

一、什麼是快速排序

引用百度百科的解釋:快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。

二、快速排序實現過程

1、分析過程

首先,在這一串數字中挑一個基準數,作爲排序的參考,將大於該基準數的數字放在後面,小於基準數的數字放在前面。

然後,這樣一來,一串數字分成了兩部分,左部分都比基準數小,右部分都比基準數大。接着,同樣的方法,再分別從左右部分都挑出一個基準數,同樣作爲排序的參考,同樣將大於該基準數的數字放在後面,小於基準數的數字放在前面。

以此類推,直至大小排序完成爲止。

2、具體數字模擬過程

  • 假設有如下一串數字:“22,1,43,23,6,34,2,7,22,88,32,54”
  • 爲了方便,我們將第一個數字22作爲基準數。
  • 假設一“探針”從右往前遍歷找到一個比22小的數,然後另一“探針”從左往右遍歷找到一個比22大的數,交換它們位置。直到兩“探針”相遇,此時左邊的都比22小,右邊的都比22大。
  • 然後將分割好數字串的按以上方法排序

a:右探針從右往左勘測,找到比22小的數,那麼探針停在7位置上;

b:左探針從左往右勘測,找到比22大的數,那麼探針停在43位置上;

c:交換7和43;
如下圖:
在這裏插入圖片描述
繼續a步驟:右探針找到比22小的數,探針停在了2位置上;
繼續b步驟:左探針找到比22大的數,探針停在了23位置上;
繼續c步驟:交換2和23
如下圖:
在這裏插入圖片描述
繼續a步驟:右探針找到比22小的數,探針停在了6位置上;
繼續b步驟:左探針右移與右探針重合,發現6比22小,那麼交換6和22
如下圖:
在這裏插入圖片描述
最終,整串數字被22分割成兩部分,左邊全部比22小,右邊全部比22大。
然後,以此類推,按照上述方法,將左右部分分別排序,如下左半部分排序:
在這裏插入圖片描述
同理,可得出右半部分排序。

三、快速排序代碼實現和效率

1、代碼

public static void main(String[] args) {
        int[] array = {22,1,43,23,6,34,2,7,22,88,32,54};
        int start = 0;
        int end = array.length - 1;
        quickSort(array, start, end);
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
    }
    public static void quickSort(int[] a, int left, int right) {
        int start = left;
        int end = right;
        int key = a[left];
        while (end > start) {
            // 從後往前比較,如果沒有比關鍵值小的,比較下一個,直到有比關鍵值小的交換位置
            while (end > start && a[end] >= key)
                end--;
            if (a[end] <= key) {
                // 如果比基準數小交換位置
                int temp = a[end];
                a[end] = a[start];
                a[start] = temp;
            }
            // 從前往後比較,如果沒有比關鍵值大的,比較下一個,直到有比關鍵值大的交換位置
            while (end > start && a[start] <= key)
                start++;
            if (a[start] >= key) {
                // 如果比基準數大交換位置
                int temp = a[start];
                a[start] = a[end];
                a[end] = temp;
            }
            // 左右探針重合後,以基準值分爲左右兩部分,左邊都比基準值小,右邊都比基準值大
        }
        // 然後遞歸,直到排完所有數字
        if (start > left) quickSort(a, left, start - 1);
        if (end < right) quickSort(a, end + 1, right);
    }

2、效率

快速排序(Quicksort)是對冒泡排序的一種改進。

那麼以下是十萬個隨機數通過兩種排序方式用時的對比:

(1)代碼

 public static void main(String[] args) {
        int a[] = new int[100000];
        // 生成10萬個隨機數
        for (int i = 0; i < 100000; i++) {
            int num = (int) (Math.random() * 100000);
            a[i] = num;
        }
        int b[] = a;

        long l = System.currentTimeMillis();
        int start = 0;
        int end = a.length - 1;
        quickSort(a, start, end);
        System.out.println("100000個隨機數快速排序用時 = " + (System.currentTimeMillis() - l));

        long s = System.currentTimeMillis();
        // 冒泡排序
        bubooSort(b);
        System.out.println("100000個隨機數冒泡排序用時 = " + (System.currentTimeMillis() - s));
    }
    public static void quickSort(int[] a, int left, int right) {
        int start = left;
        int end = right;
        int key = a[left];
        while (end > start) {
            // 從後往前比較,如果沒有比關鍵值小的,比較下一個,直到有比關鍵值小的交換位置
            while (end > start && a[end] >= key)
                end--;
            if (a[end] <= key) {
                // 如果比基準數小交換位置
                int temp = a[end];
                a[end] = a[start];
                a[start] = temp;
            }
            // 從前往後比較,如果沒有比關鍵值大的,比較下一個,直到有比關鍵值大的交換位置
            while (end > start && a[start] <= key)
                start++;
            if (a[start] >= key) {
                // 如果比基準數大交換位置
                int temp = a[start];
                a[start] = a[end];
                a[end] = temp;
            }
            // 左右探針重合後,以基準值分爲左右兩部分,左邊都比基準值小,右邊都比基準值大
        }
        // 然後遞歸,直到排完所有數字
        if (start > left) quickSort(a, left, start - 1);
        if (end < right) quickSort(a, end + 1, right);
    }
    private static void bubooSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

(2)輸出結果

100000個隨機數快速排序用時 = 58
100000個隨機數冒泡排序用時 = 2884

在10萬條數據時,所用時間長短顯而易見,那麼在大數據情況下,這種對比將更加明顯。所以可以得出:快速排序是對冒泡排序的優化和改進。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章